/**
 * Copyright (C), 2019-2023,
 * FileName: XgkService
 * Author:   fanxquer
 * Date:     2023/7/6 15:47
 * Description: Xgk三方接口服务
 * History:
 * <author>          <time>          <version>          <desc>
 * 邱富康           2023/7/6           1.0
 */
package com.hsteach.framework.web.service;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONReader;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.hsteach.common.config.App;
import com.hsteach.common.config.AppConfig;
import com.hsteach.common.core.domain.model.*;
import com.hsteach.common.enums.MenuListSourceEnum;
import com.hsteach.common.exception.ServiceException;
import com.hsteach.common.exception.XgkTokenException;
import com.hsteach.common.utils.DistinctKeyUtil;
import com.hsteach.common.utils.SecurityUtils;
import com.hsteach.common.utils.StringUtils;
import com.hsteach.framework.feign.ClientConstant;
import com.hsteach.framework.feign.IdentityEnum;
import com.hsteach.framework.feign.client.auth.AuthClient;
import com.hsteach.framework.feign.client.auth.dto.AuthResp;
import com.hsteach.framework.feign.client.xgk.PreschoolXgkClient;
import com.hsteach.framework.feign.client.xgk.XgkClient;
import com.hsteach.framework.feign.client.xgk.dto.*;
import com.hsteach.framework.feign.client.xgk.dto.ret.*;
import com.hsteach.framework.feign.client.xgk.dto.ret.AreaSchoolRet;
import com.hsteach.framework.web.TeacherJobEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 〈auth三方接口服务〉
 *
 * @author Qiu Fukang
 * @create 2023/7/6
 * @since 1.0.0
 */
@Service
@Slf4j
public class AuthService {

    @Autowired
    private AuthClient authClient;

    @Autowired
    private XgkClient xgkClient;

    @Autowired
    private AppConfig appConfig;

    @Autowired
    private PreschoolXgkClient preschoolXgkClient;

    @Value("${interface.upload.domain:http://110.185.174.59:10881}")
    private String storageUrl;




    public JSONObject userBasicInfo(String accessToken, String appToken) {
        HttpHeaders headers = new HttpHeaders();
        headers.add(ClientConstant.AUTH_ACCESS_TOKEN, accessToken);
        headers.add(ClientConstant.AUTH_APP_TOKEN, appToken);
        AuthResp<JSONObject> resp = authClient.userBasicInfo(accessToken, appToken, 0);
        if (isSuccess(resp)) {
            return  resp.getResult();
        } else {
            throw new ServiceException("auth api error: " + resp.getMessage());
        }
    }

    public JSONObject edugovTeacherInfo(String accessToken, String appToken, String id) {
        HttpHeaders headers = new HttpHeaders();
        headers.add(ClientConstant.AUTH_ACCESS_TOKEN, accessToken);
        headers.add(ClientConstant.AUTH_APP_TOKEN, appToken);
        headers.add(ClientConstant.AUTH_OPERATE_CODE, ClientConstant.AUTH_OPERATE_CODE_DEFAULT);
        AuthResp<JSONObject> resp = authClient.edugovTeacherInfo(headers, id, null, null, null);
        if (isSuccess(resp)) {
            return  resp.getResult();
        } else {
            throw new ServiceException("auth api error: " + resp.getMessage());
        }
    }

    public JSONObject teacherInfo(String accessToken, String appToken, String id) {
        HttpHeaders headers = new HttpHeaders();
        headers.add(ClientConstant.AUTH_ACCESS_TOKEN, accessToken);
        headers.add(ClientConstant.AUTH_APP_TOKEN, appToken);
        headers.add(ClientConstant.AUTH_OPERATE_CODE, ClientConstant.AUTH_OPERATE_CODE_DEFAULT);
        AuthResp<JSONObject> resp = authClient.teacherInfo(accessToken, appToken, ClientConstant.AUTH_OPERATE_CODE_DEFAULT, null, id, null, null);
        if (isSuccess(resp)) {
            return  resp.getResult();
        } else {
            throw new ServiceException("auth api error: " + resp.getMessage());
        }
    }

    public JSONObject parentInfo(String accessToken, String appToken, String id) {
        HttpHeaders headers = new HttpHeaders();
        headers.add(ClientConstant.AUTH_ACCESS_TOKEN, accessToken);
        headers.add(ClientConstant.AUTH_APP_TOKEN, appToken);
        headers.add(ClientConstant.AUTH_OPERATE_CODE, ClientConstant.AUTH_OPERATE_CODE_DEFAULT);
        AuthResp<JSONObject> resp = authClient.parentInfo(accessToken, appToken, ClientConstant.AUTH_OPERATE_CODE_DEFAULT, id);
        if (isSuccess(resp)) {
            return  resp.getResult();
        } else {
            throw new ServiceException("auth api error: " + resp.getMessage());
        }
    }

//    public AuthInfo getLoginInfo(String accessToken, String appId, String token, String orgCode, String personId, String currentStudentId) {
//        String appToken = getAppToken(appId);
//        JSONObject json = userBasicInfo(accessToken, appToken);
////        String userId = json.getString("accountId");
//        String userId = json.getString("userId");
//        JSONArray users = json.getJSONArray("users");
//        String identity = "";
//        for (int i = 0;i < users.size(); i++) {
//            JSONObject jsonObject = users.getJSONObject(i);
//            String userId1 = jsonObject.getString("userId");
//            if (userId.equals(userId1)) {
//                identity = jsonObject.getString("identity");
//            }
//        }
//        IdentityEnum identityEnum = IdentityEnum.getByCode(identity);
//        switch (identityEnum) {
//            case ADMIN:
//                return buildAdmin(accessToken, appToken, token, orgCode, personId, json, appId);
//            case TEACHER:
//                return buildTeacher(accessToken, appToken, token, orgCode, personId, json, appId);
//            case PARENT:
//                return buildParent(accessToken, appToken, token, orgCode, personId, json, appId, currentStudentId);
//            default:
//                throw new ServiceException("未知角色");
//        }
//    }


    public AuthInfo getLoginInfo(String accessToken, String appId, String token, String orgCode, String personId, String currentStudentId, String source , String menuListSource) {
        String appToken = getAppToken(appId);
        JSONObject json = userBasicInfo(accessToken, appToken);
//        String userId = json.getString("accountId");
        String userId = json.getString("userId");
        JSONArray users = json.getJSONArray("users");
        String identity = "";
        String organizeId = null;
        String orgType = "";
        String organizeName = "";
        for (int i = 0;i < users.size(); i++) {
            JSONObject jsonObject = users.getJSONObject(i);
            String userId1 = jsonObject.getString("userId");
            if (userId.equals(userId1)) {
                identity = jsonObject.getString("identity");
                organizeId = jsonObject.getString("organizeId");
                orgType = jsonObject.getString("organizeType");
                organizeName = jsonObject.getString("organizeName");
            }
        }
        IdentityEnum identityEnum = IdentityEnum.getByCode(identity);
        if("pre".equals(source)) {
//            List<PermissionMenuRep> userPermission = getUserPermission(accessToken, appId);
//            if (isSchoolAdmin(userPermission, appId)){
//                identityEnum = IdentityEnum.ADMIN;
//            }
            AuthInfo authInfo = buildUser(accessToken, appToken, json, organizeId, identityEnum.getCode());
//            authInfo.setJobList(new ArrayList<>());
            authInfo.setDutys(getAllDutys(json.getString("personId"), organizeId));
            return authInfo;
        } else {
            switch (identityEnum) {
                case ADMIN:
                    return buildAdmin(accessToken, appToken, token, orgCode, personId, json, appId,orgType,organizeId,organizeName,menuListSource);
                case TEACHER:
                    return buildTeacher(accessToken, appToken, token, orgCode, personId, json, appId,organizeId,organizeName,menuListSource);
                case PARENT:
                    return buildParent(accessToken, appToken, token, orgCode, personId, json, appId, currentStudentId,organizeId,organizeName,menuListSource);
                case EDUGOV_TEACHER:
                    return buildArea(accessToken,IdentityEnum.EDUGOV_TEACHER.getCode(),appToken,orgCode,personId,json,appId,organizeId);
                default:
                    throw new ServiceException("未知角色");
            }
        }
    }

    public List<JSONObject> getAllDutys(String person_id, String school_id) {
        XgkDataResp<JSONObject> resp = xgkClient.getPrePersonInfo(person_id, school_id);
        if (isSuccess2(resp)) {
            String teacherId = resp.getData().getString("teacherId");

            if (StringUtils.isBlank(teacherId)) {
                return null;
            }
            JSONObject jsonObject = new JSONObject();
            ArrayList<Long> teacherIds = new ArrayList<>();

            teacherIds.add(Long.valueOf(teacherId));
            jsonObject.put("teacherIds", teacherIds);
            XgkListResp<JSONObject> resp1 = xgkClient.getAllDutys(jsonObject);
            if (isSuccess2(resp1)) {
                return resp1.getData();
            } else {
                return null;
            }
        } else {
            return null;
        }

    }

    private AuthInfo buildUser(String accessToken, String appToken, JSONObject json, String organizeId,String identityCode) {
        AuthInfo authInfo = new AuthInfo();
        authInfo.setIdentity(identityCode);
        authInfo.setAppToken(appToken);
        authInfo.setPersonId(json.getString("personId"));
        authInfo.setAccessToken(accessToken);
        JSONArray users = json.getJSONArray("users");
        if (users != null && !users.isEmpty()) {
            authInfo.setOrganizeId(users.getJSONObject(0).getLong("organizeId"));
        }
        authInfo.setId(json.getString("userId"));
        authInfo.setName(json.getString("realName"));
//        List<Eclass> eclasses = getEclassList(accessToken,authInfo.getPersonId());

//        authInfo.setEclasses(eclasses);
        authInfo.setSchoolId(organizeId);

        return authInfo;
    }

    public String getAppToken(String appId) {
        AuthResp<JSONObject> resp = authClient.getAppToken(appId, appConfig.getConfig().getOrDefault(appId, new App()).getKey());
        if (isSuccess(resp)) {
            return resp.getResult().getString("appToken");
        } else {
            throw new ServiceException(resp.getMessage());
        }
    }

    public String getAppTokenByIdKey(String appId,String key) {
        AuthResp<JSONObject> resp = authClient.getAppToken(appId, key);
        if (isSuccess(resp)) {
            return resp.getResult().getString("appToken");
        } else {
            throw new ServiceException(resp.getMessage());
        }
    }
    public String getAccessTokenByNP() {
        AuthResp<JSONObject> resp = authClient.getAccessToken("dsc_sbwx", "dsc_sbwx123");
        if (isSuccess(resp)) {
            return resp.getResult().getString("accessToken");
        } else {
            throw new ServiceException(resp.getMessage());
        }
    }

    public String getAccessToken() {
        Map<String, Object> data = Maps.newHashMap();
        Map<String, Object> map = Maps.newHashMap();
        map.put("name", "dscgly");
        map.put("password", "123456");
        data.put("params", map);
//        AuthResp<JSONObject> resp = authClient.getAccessToken(data);
        AuthResp<JSONObject> resp = authClient.getAccessToken("dscgly", "123456");
        if (isSuccess(resp)) {
            return resp.getResult().getString("accessToken");
        } else {
            throw new ServiceException(resp.getMessage());
        }
    }

    public AuthInfo getWebLoginInfo(String orgCode, String token, String accessToken, String appId) {
        GetSessionInfoRet sessionInfo = getSessionInfo(orgCode, token);
        AuthInfo authInfo = new AuthInfo();
        authInfo.setAppId(appId);
        authInfo.setOrgCode(sessionInfo.getOrgCode());
        authInfo.setXgkToken(sessionInfo.getToken());
        authInfo.setId(sessionInfo.getPersonId());
        authInfo.setPersonId(sessionInfo.getPersonId());
        authInfo.setSex(sessionInfo.getSex());
        authInfo.setName(sessionInfo.getPersonName());
        authInfo.setIdentity(sessionInfo.getCurIdentity());
        if (StringUtils.isNotEmpty(sessionInfo.getAvatarUrl())) {
            authInfo.setAvatarUrl(storageUrl + "/files" + sessionInfo.getAvatarUrl());
        }
        if (StringUtils.isNotEmpty(accessToken)) {
            authInfo.setAccessToken(accessToken);
        }
        if (StringUtils.isNotEmpty(appId)) {
            String appToken = getAppToken(appId);
            authInfo.setAppToken(appToken);
        }
        return authInfo;
    }

    public LoginByAccessTokenRet getToken(String accessToken, String appToken, String appId, Long timeStamp, String encryptToken) {
        LoginByAccessTokenEntity entity = new LoginByAccessTokenEntity();
        entity.setAccessToken(accessToken);
        entity.setAppToken(appToken);
        XgkReq<LoginByAccessTokenEntity> req = new XgkReq<>();
        req.setData(entity);
        XgkDataResp<LoginByAccessTokenRet> resp = xgkClient.loginByAccessToken(appToken, timeStamp, appId, req);
        if (isSuccess(resp)) {
            return resp.getData();
        } else {
            throw new ServiceException("xgk api error: " + resp.getMessage());
        }
    }

    public GetSessionInfoRet getSessionInfo(String orgCode, String token) {
        XgkReq<JSONObject> req = new XgkReq<>();
        req.setData(new JSONObject());
        XgkDataResp<GetSessionInfoRet> resp = xgkClient.getSessionInfo(token, orgCode, req);
        if (isSuccess(resp)) {
            return resp.getData();
        } else {
            throw new ServiceException("xgk api error: " + resp.getMessage());
        }
    }

    public GetPersonRelationsRet getPersonRelations(String token, String orgCode, String personId) {
        GetPersonRelationsEntity entity = new GetPersonRelationsEntity();
        entity.setPersonId(personId);
        XgkReq<GetPersonRelationsEntity> req = new XgkReq<>();
        req.setData(entity);
        XgkDataResp<GetPersonRelationsRet> resp = xgkClient.getPersonRelations(token, orgCode, req);
        if (isSuccess(resp)) {
            return resp.getData();
        } else {
            throw new ServiceException("xgk api error: " + resp.getMessage());
        }
    }

    public String getPersonIdByThirdPersonId(String thirdId, String token, String orgCode) {
        GetPersonIdByThirdPersonIdEntity entity = new GetPersonIdByThirdPersonIdEntity();
        entity.setThirdId(thirdId);
        XgkReq<GetPersonIdByThirdPersonIdEntity> req = new XgkReq<>();
        req.setData(entity);
        XgkDataResp<String> resp = xgkClient.getPersonIdByThirdPersonId(token, orgCode, req);
        if (isSuccess(resp)) {
            return resp.getData();
        } else {
            throw new ServiceException("xgk api error: " + resp.getMessage());
        }
    }

    /**
     * 根据personId查询学生
     * @param personIds
     * @return
     */
    public List<PersonInfoRet> getStudentByPersonIds(List<String> personIds, String token, String orgCode) {
        XgkReq<GetStudentListByPersonIdsEntity> req = new XgkReq();
        GetStudentListByPersonIdsEntity data = new GetStudentListByPersonIdsEntity();
        data.setPersonIds(personIds);
        req.setData(data);
        XgkListResp<PersonInfoRet> resp = xgkClient.getPersonInfoListNoToken(token, orgCode, req);
        if (isSuccess(resp)) {
            return  resp.getData();
        } else {
            throw new ServiceException("Xgk api error: " + resp.getMessage());
        }
    }

    private AuthInfo buildTeacher(String accessToken, String appToken, String token, String orgCode, String personId, JSONObject json, String appId,String organizeId,String organizeName,String menuListSource) {
        AuthInfo authInfo = new AuthInfo();
        authInfo.setAppId(appId);
        PersonInfoRet personInfo = getPersonByPersonIds(personId,token,orgCode);
        authInfo.setIdentity(IdentityEnum.TEACHER.getCode());
//        LoginByAccessTokenRet token = getToken(accessToken, appToken);
        authInfo.setXgkToken(token);
        authInfo.setPersonId(personId);
        authInfo.setOrgCode(orgCode);
        authInfo.setAppToken(appToken);
        authInfo.setAccessToken(accessToken);
        JSONArray users = json.getJSONArray("users");
        authInfo.setOrganizeId(organizeId != null ? Long.valueOf(organizeId):null);
        authInfo.setId(json.getString("userId"));
        authInfo.setName(json.getString("realName"));
        authInfo.setMobile(personInfo.getMobile());
        authInfo.setSchoolName(organizeName);
        GetPersonRelationsRet personRelations = getPersonRelations(authInfo.getXgkToken(), authInfo.getOrgCode(), authInfo.getPersonId());
        List<Eclass> eclasses = Lists.newArrayList();
        if (personRelations.getOrganizationList().size() > 0) {
            authInfo.setOrganizationList(personRelations.getOrganizationList());
        }
        if (personRelations.getJobList().size() > 0) {
            authInfo.setJobList(personRelations.getJobList());
            eclasses = personRelations.getJobList().stream().filter(e -> TeacherJobEnum.inTeacherJobByName(e.getJobName())).map(e -> {
                Eclass eclass = new Eclass();
                eclass.setEclassId(e.getClassId());
                eclass.setClassIdTemp(e.getClassIdTemp());
                eclass.setJobId(e.getJobId());
                eclass.setJobName(e.getJobName());
                eclass.setEclassName(e.getClassName());
                return eclass;
            }).filter(DistinctKeyUtil.distinctByKey(Eclass::getEclassId)).collect(Collectors.toList());
        }
        authInfo.setEclasses(eclasses);
        //从不同的远程接口获取MenuList
        if (MenuListSourceEnum.DEVICE_SOURCE.getCode().equals(menuListSource)) {
            GetUserInfoRet2 userInfo2 = getUserInfo2(accessToken, appId);
            //数据适配，将MenuList2转化为MenuList  //TODO  注意这里，可能会出问题，转化字段不匹配或者丢失
            List<MenuList> menuList = convertMenuList2ToMenuListWithAll(userInfo2.getMenuList());
            authInfo.setMenuList(menuList);
        }else {
            GetUserInfoRet userInfo = getUserInfo(orgCode, token, appId);
            authInfo.setMenuList(userInfo.getMenuList());
        }
        return authInfo;
    }

    private AuthInfo buildParent(String accessToken, String appToken, String token, String orgCode, String personId, JSONObject json, String appId,String currentStudentId,String organizeId,String organizeName,String menuListSource) {
        AuthInfo authInfo = new AuthInfo();
        authInfo.setAppId(appId);
        authInfo.setIdentity(IdentityEnum.PARENT.getCode());
//        LoginByAccessTokenRet token = getToken(accessToken, appToken);
        authInfo.setXgkToken(token);
        authInfo.setPersonId(personId);
        authInfo.setOrgCode(orgCode);
        authInfo.setAppToken(appToken);
        authInfo.setAccessToken(accessToken);
        JSONArray users = json.getJSONArray("users");
        authInfo.setOrganizeId(organizeId != null ? Long.valueOf(organizeId):null);
        authInfo.setId(json.getString("userId"));
        authInfo.setName(json.getString("showName"));
        getPersonRelations(token, orgCode, personId);
        JSONObject userInfo = parentInfo(accessToken, appToken, json.getString("personId"));
        authInfo.setSex(userInfo.getString("sex"));
        authInfo.setMobile(userInfo.getString("mobile"));
        authInfo.setSchoolName(organizeName);
        if (StringUtils.isNotEmpty(currentStudentId)) {
            authInfo.setCurrentStudentId(currentStudentId);
            List<Children> children = userInfo.getList("children", Children.class, JSONReader.Feature.FieldBased);
            Children curretnS = children.stream().filter(e -> e.getStudentId().equals(currentStudentId)).findFirst().orElse(null);
            if (curretnS == null) {
                throw new ServiceException("家长下未查找到当前选择学生");
            }
            String studentPersonId = getPersonIdByThirdPersonId(currentStudentId, token, orgCode);
            List<PersonInfoRet> personInfo = getStudentByPersonIds(Lists.newArrayList(studentPersonId), token, orgCode);
            if (personInfo.size() > 0) {
                PersonInfoRet personInfoRet = personInfo.get(0);
                Children jcChildren = new Children();
                jcChildren.setEclassId(personInfoRet.getCurrentClass());
                jcChildren.setEclassName(personInfoRet.getCurrentClassName());
                jcChildren.setStudentId(personInfoRet.getPersonId());
                jcChildren.setStudentName(personInfoRet.getName());
                jcChildren.setSex(personInfoRet.getSex());
                authInfo.setCurrentStudent(jcChildren);
            }
        }
        //从不同的远程接口获取MenuList
        if (MenuListSourceEnum.DEVICE_SOURCE.getCode().equals(menuListSource)) {
            GetUserInfoRet2 userInfo2 = getUserInfo2(accessToken, appId);
            //数据适配，将MenuList2转化为MenuList  //TODO  注意这里，可能会出问题，转化字段不匹配或者丢失
            List<MenuList> menuList = convertMenuList2ToMenuListWithAll(userInfo2.getMenuList());
            authInfo.setMenuList(menuList);
        }else {
            GetUserInfoRet roleInfo = getUserInfo(orgCode, token, appId);
            authInfo.setMenuList(roleInfo.getMenuList());
        }
        return authInfo;
    }

    private AuthInfo buildAdmin(String accessToken, String appToken, String token, String orgCode, String personId, JSONObject json, String appId,String orgType,String organizeId,String organizeName,String menuListSource) {
       if (orgType.equals("61")||orgType.equals("62")){
           return this.buildArea(accessToken,IdentityEnum.ADMIN.getCode(),appToken,orgCode,personId,json,appId,organizeId);
       }
        AuthInfo authInfo = new AuthInfo();
        authInfo.setAppId(appId);
        authInfo.setIdentity(IdentityEnum.ADMIN.getCode());
//        LoginByAccessTokenRet token = getToken(accessToken, appToken);
        authInfo.setXgkToken(token);
        authInfo.setPersonId(personId);
        authInfo.setOrgCode(orgCode);
        authInfo.setAppToken(appToken);
        authInfo.setAccessToken(accessToken);
        JSONArray users = json.getJSONArray("users");
        authInfo.setOrganizeId(organizeId != null ? Long.valueOf(organizeId):null);
        authInfo.setId(json.getString("accountId"));
        authInfo.setName(json.getString("showName"));
        authInfo.setSchoolName(organizeName);
        //从不同的远程接口获取MenuList
        if (MenuListSourceEnum.DEVICE_SOURCE.getCode().equals(menuListSource)) {
            GetUserInfoRet2 userInfo2 = getUserInfo2(accessToken, appId);
            //数据适配，将MenuList2转化为MenuList  //TODO  注意这里，可能会出问题，转化字段不匹配或者丢失
            List<MenuList> menuList = convertMenuList2ToMenuListWithAll(userInfo2.getMenuList());
            authInfo.setMenuList(menuList);
        }else {
            GetUserInfoRet userInfo = getUserInfo(orgCode, token, appId);
            authInfo.setMenuList(userInfo.getMenuList());
        }
        return authInfo;
    }


    /**
     * 将List<MenuList2> 转化为 List<MenuList>
     */
    private List<MenuList> convertMenuList2ToMenuListWithAll(List<MenuList2> menuList2s) {
        if (ObjectUtils.isEmpty(menuList2s)) {
            return new ArrayList<>();
        }
        ArrayList<MenuList> result = new ArrayList<>();
        for (MenuList2 menuList2 : menuList2s) {
            result.add(convertMenuList2ToMenuList(menuList2));
        }
        return result;
    }

    /**
     * 将MenuList2对象递归转换为MenuList对象。
     * @param menuList2 输入的MenuList2对象。
     * @return 转换后的MenuList对象。
     */
    private MenuList convertMenuList2ToMenuList(MenuList2 menuList2) {
        // 创建新的MenuList对象
        MenuList menuList = new MenuList();
        menuList.setAppId(menuList2.getAppId());
        menuList.setName(menuList2.getName());
        menuList.setSpyCode(menuList2.getSpyCode());
        menuList.setSpyParentCode(menuList2.getSpyParentCode());

        // 如果有子节点，进行转换
        if (menuList2.getChildren() != null && !menuList2.getChildren().isEmpty()) {
            List<MenuList> convertedChildren = new ArrayList<>();
            for (MenuList2 child : menuList2.getChildren()) {
                // 递归转换子节点
                MenuList convertedChild = convertMenuList2ToMenuList(child);
                convertedChildren.add(convertedChild);
            }
            menuList.setChildren(convertedChildren);
        }

        return menuList;
    }

    private AuthInfo buildArea(String accessToken,String identity,String  appToken, String orgCode, String personId, JSONObject json, String appId,String organizeId) {
        AuthInfo authInfo = new AuthInfo();
        authInfo.setAppId(appId);
        authInfo.setIdentity(identity);
        authInfo.setPersonId(personId);
        authInfo.setOrgCode(orgCode);
        authInfo.setAppToken(appToken);
        authInfo.setAccessToken(accessToken);
        JSONArray users = json.getJSONArray("users");
        authInfo.setOrganizeId(organizeId != null ? Long.valueOf(organizeId):null);
        authInfo.setId(json.getString("accountId"));
        authInfo.setName(json.getString("realName"));
        authInfo.setAvatarUrl(json.getString("photo"));
        return authInfo;
    }

    private boolean isSuccess(AuthResp resp) {
        if (ClientConstant.AUTH_SUCCESS.equals(resp.getStatus())) {
            return true;
        }
        return false;
    }

    private GetUserInfoRet getUserInfo(String orgCode, String token, String appId) {
        XgkReq<GetUserInfoEntity> req = new XgkReq<>();
        GetUserInfoEntity entity = new GetUserInfoEntity();
        entity.setAppId(appConfig.getConfig().getOrDefault(appId, new App()).getAuthAppId());
        entity.setAppAlias(appConfig.getConfig().getOrDefault(appId, new App()).getAuthAppAlias());
        req.setData(entity);
        XgkDataResp<GetUserInfoRet> resp = xgkClient.getUserInfo(token, orgCode, req);
        if (isSuccess(resp)) {
            return resp.getData();
        } else {
            throw new ServiceException("xgk api error: " + resp.getMessage());
        }
    }

    /**
     * 获取用户信息
     * 这里的orgCode是修改之后遗留的，没有使用
     */
    private GetUserInfoRet2 getUserInfo2(String accessToken, String appId) {
        XgkListResp2<GetUserInfoRet2> resp = preschoolXgkClient.getUserInfo2(accessToken, appId);
        if (isSuccess4(resp)) {
            //返回null
            if (ObjectUtils.isEmpty(resp) || ObjectUtils.isEmpty(resp.getData())) {
                GetUserInfoRet2 getUserInfoRet2 = new GetUserInfoRet2();
                getUserInfoRet2.setMenuList(new ArrayList<>());
                return getUserInfoRet2;
            }else {
                return resp.getData().get(0);
            }
        } else {
            throw new ServiceException("xgk api error: " + resp.getMessage());
        }
    }

    private boolean isSuccess(XgkResp resp) {
        if (StringUtils.isNotEmpty(resp.getMessage()) && resp.getMessage().indexOf("用户令牌己更新") != -1) {
            throw new XgkTokenException(resp.getMessage());
        }
        if (ClientConstant.XGK_SUCCESS.equals(resp.getCode())) {
            return true;
        }
        return false;
    }

    private boolean isSuccess2(XgkResp resp) {
        if (StringUtils.isNotEmpty(resp.getMessage()) && resp.getMessage().indexOf("用户令牌己更新") != -1) {
            throw new XgkTokenException(resp.getMessage());
        }
        if (ClientConstant.XGK_ISCMS_SUCCESS.equals(resp.getCode())) {
            return true;
        }
        return false;
    }

    private boolean isSuccess3(XgkResp resp) {
        if (StringUtils.isNotEmpty(resp.getMessage()) && resp.getMessage().indexOf("用户令牌己更新") != -1) {
            throw new XgkTokenException(resp.getMessage());
        }
        if (ClientConstant.XGK_SUCCESS.equals(resp.getStatus())) {
            return true;
        }
        return false;
    }

    private boolean isSuccess4(XgkResp2 resp) {
        //null值正常
        if (ObjectUtils.isEmpty(resp)){
            return true;
        }
        if (StringUtils.isNotEmpty(resp.getMessage()) && resp.getMessage().indexOf("用户令牌己更新") != -1) {
            throw new XgkTokenException(resp.getMessage());
        }
        if (Integer.toString(ClientConstant.AUTH_SUCCESS).equals(resp.getHttpStatusCode()) && ClientConstant.XGK_ISCMS_SUCCESS.equals(resp.getCode())) {
            return true;
        }
        return false;
    }

    public PersonInfoRet getPersonByPersonIds(String personId,String token, String orgCode) {
        XgkReq<GetStudentListByPersonIdsEntity> req = new XgkReq();
        GetStudentListByPersonIdsEntity data = new GetStudentListByPersonIdsEntity();
        data.setPersonIds(Collections.singletonList(personId));
        req.setData(data);
        XgkListResp<PersonInfoRet> resp = xgkClient.getPersonInfoListNoToken(token,orgCode,req);
        if (isSuccess(resp) && resp.getData().size()>0) {
            return  resp.getData().get(0);
        } else {
            throw new ServiceException("Xgk api error: " + resp.getMessage());
        }
    }

    @Cacheable(cacheNames = "areaSchoolStudent", key = "#schoolId")
    public List<AreaStudentRet> getStudentBySchoolId(String schoolId) {
        AuthInfo authInfo = SecurityUtils.getAuthInfo();
        XgkListResult<AreaStudentRet> resp = authClient.getStudentBySchoolId(authInfo.getAccessToken(),authInfo.getAppToken(),"J",schoolId);
        if (isSuccess3(resp)) {
            return  resp.getResult();
        } else {
            throw new ServiceException("Xgk api error: " + resp.getMessage());
        }
    }

    /**
     * 查询所有学校
     * @param
     * @return
     */
    @Cacheable(cacheNames = "allSchool", key = "#area")
    public List<AreaSchoolRet> getSchool(String area) {
        AuthInfo authInfo = SecurityUtils.getAuthInfo();
        XgkListResult<AreaSchoolRet> resp = authClient.getSchool(authInfo.getAccessToken(),authInfo.getAppToken(),"J");
        if (isSuccess3(resp)) {
            return  resp.getResult();
        } else {
            throw new ServiceException("Xgk api error: " + resp.getMessage());
        }
    }

    public Map<String, List<AreaClassRet>> getAllClassBySchoolId(String schoolId) {
        AuthInfo authInfo = SecurityUtils.getAuthInfo();
        XgkResult<XgkList<AreaClassRet>> resp = authClient.getAllClassBySchoolId(999,schoolId,authInfo.getAccessToken(),authInfo.getAppToken(),"J");
        if (isSuccess3(resp)) {
            List<AreaClassRet> respResult = resp.getResult().getList();
            Map<String, String> grandName = getGrandName();
            return respResult.stream()
                    .peek(e -> e.setGradeName(grandName.get(e.getGrade())))
                    .collect(Collectors.groupingBy(AreaClassRet::getGradeName));
        }else {
            throw new ServiceException("Xgk api error: " + resp.getMessage());
        }
    }


    public Map<String,String> getGrandName() {
        AuthInfo authInfo = SecurityUtils.getAuthInfo();
        JSONObject resp = authClient.getGrandName(authInfo.getAccessToken(),authInfo.getAppToken(),"J");
        if (resp.get("status").equals(200)) {
            JSONArray results = resp.getJSONArray("result");
            List<JSONObject> jsonObjectList = results.toJavaList(JSONObject.class);
            JSONObject grade = jsonObjectList.stream()
                    .filter(jsonObject -> {
                        if (ObjectUtils.isNotEmpty(jsonObject) && jsonObject.get("key").equals("grade")) {
                            return true;
                        }
                        return false;
                    }).findFirst().orElse(null);
            JSONArray items = grade.getJSONArray("items");
            List<JSONObject> itemList = items.toJavaList(JSONObject.class);
            return itemList.stream().collect(Collectors.toMap(item -> item.getString("code"), item -> item.getString("name")));
        }else {
            throw new ServiceException("Xgk api error: " + resp.get("message"));
        }
    }
}
